#include "StdAfx.h"
#include "Helpers.h"
#include "ChainUnitTests.h"
#include "VertexDirectory.h"
//#include "GraphColoring.h"
#include "Group.h"
#include "Graph.h"
#include "Chain.h"

void CleanChainTests(VertexDirectory* dirA, VertexDirectory* dirB, Graph* graphA, Graph* graphB, 
					 Chain* chainA, Chain* chainB)
{
		delete dirA;
		delete dirB;
		delete graphA;
		delete graphB;
		delete chainA;
		delete chainB;
}

// creates 2 chains on a graph with n=9, w=4.
// chains have the same length, one is bigger than the other, and compares them 
TestUtils::TestResult CompareBiggerAndSmallerChains()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateBigChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateSmallChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) > 0,"chain's Compare method reports the smaller chain is bigger") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) < 0,"chain's Compare method reports the bigger chain is smaller") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}

// creates 2 identical chains on a graph with n=9, w=4.
// verifies they are equal
TestUtils::TestResult CompareIdenticalChains()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateBigChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateBigChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) == 0,"chain's Compare method reports identical chains aren't equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) == 0,"chain's Compare method reports identical chains aren't equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}

// creates 2 chains with the same size and verifies they are equal
TestUtils::TestResult CompareEqualChains()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateBigChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateAnotherBigChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) == 0,"chain's Compare method reports equal chains aren't equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) == 0,"chain's Compare method reports equal chains aren't equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}

// creates 2 chains with the same number of groups and same group sizes,
// in the first chain the sizes are: 3,3,2.
// in the second chain the sizes are: 3,2,3. 
// Validates the first chain is bigger
TestUtils::TestResult CompareSimilarNonEqualChains()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateBigChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateMixedBigChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) > 0,"chain's Compare non-equal chains as equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) < 0,"chain's Compare non-equal chains as equal") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}

// creates 2 chains with the same number of vertices, but one is longer than the other.
// the shorter one should be reported as bigger
// in the first chain the sizes are: 3,2,1.
// in the second chain the sizes are: 3,3. 
// Validates the second chain is bigger
TestUtils::TestResult CompareSmallerLongerChain()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateShortChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateSmallChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) > 0,"chain's Compare reports the bigger shain is smaller") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) < 0,"chain's Compare reports the smaller chain is bigger") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}

// creates 2 chains:
// in the first chain the group sizes are: 3,3,2,1.
// in the second chain the sizes are: 3,2,1. 
// Validates the first chain is bigger
TestUtils::TestResult CompareBiggerLongerChain()
{
	int n=7;
	int w=4;
	TestUtils::CreateVertexDirectory(n,w);
	VertexDirectory* dirA = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	VertexDirectory* dirB = new VertexDirectory(VertexDirectory::GetStaticCopyVertices());
	Graph* graphA = TestUtils::CreateGraphFromDirectory(dirA->GetWorkingCopyVertices(), dirA);
	Graph* graphB = TestUtils::CreateGraphFromDirectory(dirB->GetWorkingCopyVertices(), dirB);
	Chain* chainA = new Chain(graphA,dirA);		
	chainA = TestUtils::CreateBigLongChain7On2With3Groups(chainA);
	Chain* chainB = new Chain(graphB,dirB);		
	chainB = TestUtils::CreateSmallChain7On2With3Groups(chainB);
	if (TestUtils::VerifyIsTrue(chainA->Compare(chainB) > 0,"chain's Compare reports the bigger shain is smaller") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	if (TestUtils::VerifyIsTrue(chainB->Compare(chainA) < 0,"chain's Compare reports the smaller chain is bigger") == TestUtils::TestFailed)
	{
		CleanChainTests(dirA, dirB, graphA, graphB, chainA, chainB);
		return TestUtils::TestFailed;
	}
	
	return TestUtils::TestPassed;
}



